package com.lingjtx.common.security.aop;

import com.lingjtx.common.core.ResponseResult;
import com.lingjtx.common.redis.service.IRedisService;
import com.lingjtx.common.security.limit.ApiContext;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Objects;

@Component
@Aspect
@Order(2)
public class ApiHandlerAspect {

    private final IRedisService redisService;
    private final ApiContext<ProceedingJoinPoint, HttpServletRequest> context;

    public ApiHandlerAspect(IRedisService redisService, @Qualifier("apiStateContext") ApiContext<ProceedingJoinPoint, HttpServletRequest> context) {
        this.redisService = redisService;
        this.context = context;
    }

    @Pointcut("@annotation(com.lingjtx.common.security.annotation.ApiLimited)")
    private void aipLimitedPoint() {
    }

    @Pointcut("@annotation(com.lingjtx.common.security.annotation.NonRepeatable)")
    private void nonRepeatablePoint() {
    }

    @Pointcut("@annotation(com.lingjtx.common.core.annotation.ApiSignature)")
    private void apiSignaturePoint() {
    }

    @Around("aipLimitedPoint()||nonRepeatablePoint()||apiSignaturePoint()")
    public Object interceptor(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        Object proceeding = context.process(point, request, redisService);
        if (proceeding instanceof ResponseResult) {
            return proceeding;
        }
        return point.proceed();
    }
}
